package com.erp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.erp.common.BaseContext;
import com.erp.common.CustomException;
import com.erp.common.R;
import com.erp.common.SuperConstant;
import com.erp.dao.GeneralLedgerDao;
import com.erp.dao.ReceivableDao;
import com.erp.entity.FinancialJournal;
import com.erp.entity.GeneralLedger;
import com.erp.entity.Receivable;
import com.erp.service.FinancialJournalService;
import com.erp.service.GeneralLedgerService;
import com.erp.service.ReceivableService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class ReceivableServiceImpl extends ServiceImpl<ReceivableDao, Receivable> implements ReceivableService {

    @Autowired
    private GeneralLedgerService generalLedgerService;

    @Autowired
    private FinancialJournalService financialJournalService;

    /**
     * 向应收账表添加数据 并更新总账表 涉及到多表操作需要添加事物注解
     *
     * @param receivable
     * @return
     */
    @Override
    @Transactional
    public R<String> saveReceivableAndLedger(Receivable receivable) {
        log.info("保存应收账并更新总账");
        //设置默认字段
        receivable.setStatus(0);
        if (Objects.isNull(receivable.getCreateDateTime())) {
            receivable.setCreateDateTime(LocalDateTime.now());
        }

        //对应收账表添加数据
        this.save(receivable);

        //记录日志
        FinancialJournal financialJournal = new FinancialJournal
                (BaseContext.getCurrentId(), SuperConstant.ReceivableTable, SuperConstant.Save);
        financialJournalService.save(financialJournal);

        //条件构造器 查找generalLedger中是否有type为应收账的数据
        LambdaQueryWrapper<GeneralLedger> ledgerLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ledgerLambdaQueryWrapper.eq(GeneralLedger::getType, "应收账");
        List<GeneralLedger> list = generalLedgerService.list(ledgerLambdaQueryWrapper);

        //如果没有 则创建对象并设置默认值最后保存进数据库
        if (list.size() == 0) {
            log.info("新增总账");
            GeneralLedger generalLedger = new GeneralLedger();
            generalLedger.setMoney(receivable.getMoney());
            generalLedger.setType("应收账");
            generalLedgerService.save(generalLedger);
        } else if (list.size() == 1) {
            log.info("更新总账");
            //如果有 则取出该对象 对number字段进行修改后更新到数据库
            GeneralLedger generalLedger = list.get(0);
            generalLedger.setMoney(generalLedger.getMoney() + receivable.getMoney());
            generalLedgerService.updateById(generalLedger);
        } else {
            throw new CustomException("总账表异常，通知管理员维护");
        }

        return R.success("添加成功");
    }

    /**
     * 根据id删除总账信息
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public R<String> deleteByIdAndUpdateLedger(Long id) {
        //判断id是否存在
        Receivable receivable = this.getById(id);
        if (ObjectUtils.isEmpty(receivable)) {
            return R.error("id不存在");
        }

        //条件构造器
        LambdaQueryWrapper<GeneralLedger> ledgerLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ledgerLambdaQueryWrapper.eq(GeneralLedger::getType, "应收账");
        List<GeneralLedger> list = generalLedgerService.list(ledgerLambdaQueryWrapper);

        //判断总账分类是否存在
        if (list.size() == 0) {
            return R.error("删除异常,应收账分类不存在");
        } else if (list.size() > 1) {
            throw new CustomException("总账表异常，通知管理员维护");
        }

        Long number = receivable.getMoney();
        GeneralLedger generalLedger = list.get(0);

        //更新总账数据
        generalLedger.setMoney(generalLedger.getMoney() - number);
        generalLedgerService.updateById(generalLedger);

        //删除应收账数据
        this.removeById(id);

        //记录日志
        FinancialJournal financialJournal = new FinancialJournal
                (BaseContext.getCurrentId(), SuperConstant.ReceivableTable, SuperConstant.Delete, id.toString());
        financialJournalService.save(financialJournal);
        return R.success("删除成功");
    }


}
